﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Drawing.Drawing2D;

namespace Grizzy_X
{
    public class CLine
    {
        private int ID;
        public List<List<PointF>>Lines;
        public List<int> PolyCounts;
        public MBR MinBR;
        public int LegendID;
        public bool isselected;
        public Pen linepen;
        public PointF inter;
        public double[] Length;   //记录每条简单线的长度，最后一条记录是总长度

        public int GetID()
        {
            return ID;
        }

        public void newCline(int lnid,int legdid)
        {
            ID = lnid;
            LegendID = legdid;
            Lines = new List<List<PointF>>();
            //Lines.Add(new List<PointF>());
            PolyCounts = new List<int>();
            MinBR = new MBR();
            isselected = false;
        }

        public void addnode(PointF currentpoint)
        {
                Lines[Lines.Count() - 1].Add(currentpoint);
        }
        public void deletenode(int index1, int index2)
        {
            Lines[index1].RemoveAt(index2);
        }
        public void deletesimpleline()
        {
            for (int i = 0; i < Controller.selectsimple.Count(); i++)
            {
                Lines.RemoveAt(Controller.selectsimple[i]);
                Lines.Insert(Controller.selectsimple[i], new List<PointF>());
            }
            for (int i = 0; i <Lines.Count(); i++)
            {
                if (Lines[i].Count() == 0)
                {
                    Lines.RemoveAt(i);
                    i--;
                }
            }
        }
        public void DragLine(Point movepoint)
        {
            for (int i = 0; i < Lines.Count(); i++)
            {
                for (int j = 0; j < Lines[i].Count(); j++)
                {
                    Point screen = new Point();
                    screen = Transformer.ToScreen(Lines[i][j]);
                    screen.X = screen.X + movepoint.X;
                    screen.Y = screen.Y + movepoint.Y;
                    PointF temp = Transformer.FromScreen(screen);
                    //PointF temp = new PointF((points[i].X + movepoint.X), (points[i].Y + movepoint.Y));
                    Lines[i].RemoveAt(j);
                    Lines[i].Insert(j, temp);
                }
            }
        }
        public void DragsimpleLine(Point movepoint)
        {
            for (int i = 0; i < Controller.selectsimple.Count(); i++)
            {
                for (int j = 0; j < Lines[Controller.selectsimple[i]].Count(); j++)
                {
                    Point screen = new Point();
                    screen = Transformer.ToScreen(Lines[Controller.selectsimple[i]][j]);
                    screen.X = screen.X + movepoint.X;
                    screen.Y = screen.Y + movepoint.Y;
                    PointF temp = Transformer.FromScreen(screen);
                    //PointF temp = new PointF((points[i].X + movepoint.X), (points[i].Y + movepoint.Y));
                    Lines[Controller.selectsimple[i]].RemoveAt(j);
                    Lines[Controller.selectsimple[i]].Insert(j, temp);
                }
            }
        }
        public void DragNode(Point movepoint)
        {
            Point screen = new Point();
            screen = Transformer.ToScreen(Lines[Controller.selectnodeindex.X][Controller.selectnodeindex.Y]);
            screen.X = screen.X + movepoint.X;
            screen.Y = screen.Y + movepoint.Y;
            PointF temp = Transformer.FromScreen(screen);
            //PointF temp = new PointF((points[i].X + movepoint.X), (points[i].Y + movepoint.Y));
            Lines[Controller.selectnodeindex.X].RemoveAt(Controller.selectnodeindex.Y);
            Lines[Controller.selectnodeindex.X].Insert(Controller.selectnodeindex.Y, temp);
        }
        public void updateMBR()
        {
            List<PointF> linepoints = new List<PointF>();
            for (int i = 0; i < Lines.Count(); i++)
            {
                for (int j = 0; j < Lines[i].Count(); j++)
                    linepoints.Add(Lines[i][j]);
            }
            if(linepoints.Count()>0)
                MinBR.GetMBR(linepoints);
        }
        //wx未写完，对一条线的简单线段进行选择
        public void selectsimpleline(PointF e)
        {
            float PI = (float)Math.PI;
                float trans;
                if (Controller.MyMap.Unit == "英寸")
                    trans = (float)1 / 96;
                else
                    trans = (float)2.54 / 96;
                float Buffer = Math.Max(((CLineLegend)Controller.MapLegends[LegendID]).line_weight * trans / 2, 10 * trans);
                if (MinBR.Lx - Buffer < e.X && MinBR.Ly - Buffer < e.Y &&
                    MinBR.Rx + Buffer > e.X &&  MinBR.Ry + Buffer > e.Y)
                {
                    for (int j = 0; j < Lines.Count(); j++)
                    {
                        for (int k = 0; k + 1 < Lines[j].Count(); k++)
                        {
                            List<PointF> RecBuffer = new List<PointF>();
                            PointF P1 = Lines[j][k];
                            PointF P2 = Lines[j][k + 1];
                            float slope = (float)Math.Atan((P1.Y - P2.Y) / (P1.X - P2.X));
                            RecBuffer.Add(new PointF(P1.X + Buffer * (float)Math.Cos(slope - 0.75 * PI), P1.Y + Buffer * (float)Math.Sin(slope - 0.75 * PI)));
                            RecBuffer.Add(new PointF(P1.X + Buffer * (float)Math.Cos(slope + 0.75 * PI), P1.Y + Buffer * (float)Math.Sin(slope + 0.75 * PI)));
                            RecBuffer.Add(new PointF(P2.X + Buffer * (float)Math.Cos(slope + 0.25 * PI), P2.Y + Buffer * (float)Math.Sin(slope + 0.25 * PI)));
                            RecBuffer.Add(new PointF(P2.X + Buffer * (float)Math.Cos(slope - 0.25 * PI), P2.Y + Buffer * (float)Math.Sin(slope - 0.25 * PI)));
                            //RecBuffer.Add(new PointF(P1.X + Buffer * (float)Math.Cos(slope - 0.75 * PI), P1.Y + Buffer * (float)Math.Sin(slope - 0.75 * PI)));
                            if (Controller.IfPointInPolygon(RecBuffer, new PointF(e.X, e.Y)))
                            {
                                for (int m = 0; m < Controller.selectsimple.Count(); m++)
                                {
                                    if (j == Controller.selectsimple[m])
                                    {
                                        Controller.selectsimple.RemoveAt(m);
                                        return;
                                    }
                                }
                                //Controller.SelectedObjectType = "Line";
                                Controller.selectsimple.Add(j);
                                //isselected = true;
                            }
                        }
                    }
            }
                if (Controller.selectsimple.Count == 1)
                    MainForm.pMainWin.Split.Enabled = true;
                else
                    MainForm.pMainWin.Split.Enabled = false;
            return;
        }


        public void selectnodeorline(PointF e)
        {
            float trans;
            if (Controller.MyMap.Unit == "英寸")
                trans = (float)1 / 96;
            else
                trans = (float)2.54 / 96;
            float Buffer = 10 *trans;
            if (MinBR.Lx - Buffer < e.X &&
                MinBR.Ly - Buffer < e.Y &&
               MinBR.Rx + Buffer > e.X &&
                MinBR.Ry + Buffer > e.Y)
            {
                for (int i = 0; i < Lines.Count(); i++)
                {
                    for (int j = 0; j < Lines[i].Count(); j++)
                        if (Math.Abs(Lines[i][j].X - e.X) < Buffer
                            && Math.Abs(Lines[i][j].Y - e.Y) < Buffer)
                        {
                            if (i == Controller.selectnodeindex.X && j == Controller.selectnodeindex.Y)
                            {
                                Controller.selectnodeindex = new Point(-1,-1);
                                return;
                            }
                            Controller.selectnodeindex = new Point(i, j);
                            Controller.selectlineindex = new Point(-1,-1);
                            return;
                        }
                    float PI = (float)Math.PI;
                    Buffer = Math.Max(((CLineLegend)Controller.MapLegends[LegendID]).line_weight * trans / 2, 10 * trans);
                    for (int j = 0; j + 1 < Lines[i].Count(); j++)
                    {
                        List<PointF> RecBuffer = new List<PointF>();
                        PointF P1 = Lines[i][j];
                        PointF P2 = Lines[i][j + 1];
                        float slope = (float)Math.Atan((P1.Y - P2.Y) / (P1.X - P2.X));
                        RecBuffer.Add(new PointF(P1.X + Buffer * (float)Math.Cos(slope - 0.75 * PI), P1.Y + Buffer * (float)Math.Sin(slope - 0.75 * PI)));
                        RecBuffer.Add(new PointF(P1.X + Buffer * (float)Math.Cos(slope + 0.75 * PI), P1.Y + Buffer * (float)Math.Sin(slope + 0.75 * PI)));
                        RecBuffer.Add(new PointF(P2.X + Buffer * (float)Math.Cos(slope + 0.25 * PI), P2.Y + Buffer * (float)Math.Sin(slope + 0.25 * PI)));
                        RecBuffer.Add(new PointF(P2.X + Buffer * (float)Math.Cos(slope - 0.25 * PI), P2.Y + Buffer * (float)Math.Sin(slope - 0.25 * PI)));
                        //RecBuffer.Add(new PointF(P1.X + Buffer * (float)Math.Cos(slope - 0.75 * PI), P1.Y + Buffer * (float)Math.Sin(slope - 0.75 * PI)));
                        if (Controller.IfPointInPolygon(RecBuffer, new PointF(e.X, e.Y)))
                        {
                            if (i == Controller.selectlineindex.X && j == Controller.selectlineindex.Y)
                            {
                                Controller.selectlineindex = new Point(-1, -1);
                                return;
                            }
                            Controller.selectlineindex = new Point(i, j);
                            Controller.selectnodeindex = new Point(-1, -1);
                            return;
                        }
                    }
                }
            }
           
        }
        public bool Split(PointF p1,PointF p2)
        {
            inter = new PointF();
            if (Controller.selectsimple == null || Controller.selectsimple.Count == 0)
            {
                for (int i = 0; i + 1 < Lines[0].Count; i++)
                {
                    inter = Controller.SegmentIntersect(Lines[0][i], Lines[0][i + 1], p1, p2);
                    if (inter.X != -1 && inter.Y != -1)
                    {
                        Lines[0].Insert(i + 1, inter);
                        List<PointF> Templist = new List<PointF>();
                        Templist.Add(inter);
                        int k = Lines[0].Count;
                        for (int j = i + 2; j < k; j++)
                        {
                            Templist.Add(Lines[0][i + 2]);
                            Lines[0].RemoveAt(i + 2);
                        }
                        Lines.Add(Templist);
                        isselected = true;
                        return true;
                    }
                }
            }
            else
            {
                for (int i = 0; i + 1 < Lines[Controller.selectsimple[0]].Count; i++)
                {
                    inter = Controller.SegmentIntersect(Lines[Controller.selectsimple[0]][i], Lines[Controller.selectsimple[0]][i + 1], p1, p2);
                    if (inter.X != -1 && inter.Y != -1)
                    {
                        Lines[Controller.selectsimple[0]].Insert(i + 1, inter);
                        List<PointF> Templist = new List<PointF>();
                        Templist.Add(inter);
                        int k = Lines[Controller.selectsimple[0]].Count;
                        for (int j = i + 2; j < k; j++)
                        {
                            Templist.Add(Lines[Controller.selectsimple[0]][i + 2]);
                            Lines[Controller.selectsimple[0]].RemoveAt(i + 2);
                        }
                        Lines.Add(Templist);
                        isselected = true;
                        Controller.selectsimple.Add(Lines.Count-1);
                        return true;
                    }
                }
            }
            return false;
        }

        public void Calculate_Length()
        {
            Length=new double[Lines.Count+1];
            for (int i = 0; i < Lines.Count;i++ )
            {
                for (int j = 0; j < Lines[i].Count - 1; j++)
                {
                    Length[i]+=Math.Sqrt((Lines[i][j].X-Lines[i][j+1].X)*(Lines[i][j].X-Lines[i][j+1].X)+(Lines[i][j].Y-Lines[i][j+1].Y)*(Lines[i][j].Y-Lines[i][j+1].Y));
                }
                Length[Lines.Count] += Length[i];
            }
        }
    }
}  
